import 'isomorphic-fetch';
import {result} from '@utils/Result';

const fetchApi = self.fetch.bind(self);

const Fetch = function (api) {
  this.api = api;
  this.headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  };
  this.callbacks = {};
};
Fetch.prototype.header = function (headers) {
  this.headers = Object.assign({}, this.headers, headers);
  return this;
};
Fetch.prototype.get = function () {
  const _this = this;
  setTimeout(function () {
    _this.callApi({method: 'get'});
  });
  return this;
};
Fetch.prototype.post = function (body) {
  const _this = this;
  setTimeout(function () {
    _this.callApi({
      method: 'post',
      body: JSON.stringify(body)
    });
  });
  return this;
};
Fetch.prototype.put = function (body) {
  const _this = this;
  setTimeout(function () {
    _this.callApi({
      method: 'put',
      body: JSON.stringify(body)
    });
  });
  return this;
};
Fetch.prototype.delete = function (body) {
  const _this = this;
  setTimeout(function () {
    _this.callApi({
      method: 'delete',
      body: JSON.stringify(body)
    });
  });
  return this;
};
Fetch.prototype.upload = function (formData) {
  this.headers = null;
  return this.callApi({
    method: 'post',
    body: formData,
    processData: false,
    contentType: false
  });
};
Fetch.prototype.success = function (callback) {
  this.callbacks.success = callback;
  return this;
};
Fetch.prototype.error = function (callback) {
  this.callbacks.error = callback;
  return this;
};
Fetch.prototype.callApi = function (options) {
  try {
    let finalOptions = Object.assign({credentials: 'include'}, options);
    if (this.headers) {
      finalOptions = Object.assign({}, finalOptions, {headers: this.headers});
    }
    const {success, error} = this.callbacks || {};
    const p = fetchApi(this.api, finalOptions)
      .then(res => (typeof res === 'object') ? res.json() : res)
      .then(json => json)
      .catch(error => {
        throw error
      });
    if (!success && !error) {
      return p;
    } else {
      p.then(result().success(success).error(error).end());
    }
  } catch (err) {
    console.error(`fetch ${options.method} error : `, err);
  }
};
const fetch = function (api) {
  return new Fetch(api);
};
export {
  fetch
}
export default Fetch;

